package at.brandl.wwi;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;

public class WhereWasIPoint {
	private final long id;
	private final int time;
	private final int longitude;
	private final int latitude;
	private final int accuracy;
	private BoundaryEnum boundary;

	public WhereWasIPoint(long time, double longitude, double latitude,
			float accuracy) {
		this(-1, convertToMinutes(time),(int) (longitude * 1E6),(int) (latitude * 1E6),(int)accuracy, null);
	}

	public WhereWasIPoint(long id, int time, int longitude, int latitude,
			int accuracy, BoundaryEnum boundary) {
		this.id = id;
		this.time = time ;
		this.longitude = longitude;
		this.latitude = latitude ;
		this.accuracy = accuracy;
		this.boundary = boundary;
	}


	public long getId() {
		return id;
	}
	
	public long getTime() {
		return convertToTimeMillis(time);
	}

	public static long convertToTimeMillis(int time) {
		return time * 1000 * 60;
	}

	public long getTimeMinutes()  {
		return time;
	}
	

	public String getDateString() {
		Calendar cal = Calendar.getInstance();
		cal.setTimeInMillis(getTime());
		String format = "d.M.yy H:mm";
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		return sdf.format(cal.getTime());
	}
	
	public double getLongitude() {
		return ((double)longitude) / 1E6 ;
	}

	public int getLongitudeE6()
	{
		return longitude;
	}
	
	public double getLatitude() {
		return ((double)latitude) / 1E6;
	}
	
	public int getLatitudeE6() {
		return latitude;
	}

	public int getAccuracy() {
		return accuracy;
	}

	public BoundaryEnum getBoundary() {
		return boundary;
	}

	public void setBoundary(BoundaryEnum boundary) {
		this.boundary = boundary;
	}

	@Override
	public boolean equals(Object o) {
		if (!(o instanceof WhereWasIPoint)) {
			return false;
		}
		WhereWasIPoint other = (WhereWasIPoint) o;
		return time == other.time && equalLocation(other);
	}

	@Override
	public int hashCode() {
		int result = 17;
		result = 37 * result + Long.valueOf(time).hashCode();
		result = 37 * result + Double.valueOf(longitude).hashCode();
		result = 37 * result + Double.valueOf(latitude).hashCode();
		result = 37 * result + Double.valueOf(accuracy).hashCode();
		return result;
	}

	@Override
	public String toString() {
		return new StringBuilder().append("id:").append(id).append(" time:").append(time)
				.append(" long:").append(longitude).append(" lat:")
				.append(latitude)
				.append(" accuracy:").append(accuracy).append(" bound:")
				.append(boundary).toString();
	}

	public static enum BoundaryEnum {
		BEGIN("B"), END("E");

		private static Map<String, BoundaryEnum> TEXT2VAL = new HashMap<String, WhereWasIPoint.BoundaryEnum>();
		static {
			for (BoundaryEnum bound : BoundaryEnum.values()) {
				TEXT2VAL.put(bound.getText(), bound);
			}
		}

		private final String text;

		private BoundaryEnum(String text) {
			this.text = text;
		}

		public String getText() {
			return text;
		}

		public static BoundaryEnum valueOfText(String text) {

			return TEXT2VAL.get(text);
		}
	}

	public boolean equalLocation(WhereWasIPoint other) {
		if(other == null)
		{
			return false;
		}
		return longitude == other.longitude && latitude == other.latitude && accuracy == other.accuracy;
	}


	public static int convertToMinutes(long timeMillis) {
		return (int)timeMillis / 1000 / 60;
	}


}
